package com.authentications.oauth2.auc.handler;

import com.authentications.oauth2.auc.handler.inits.InitTokenInfo;
import com.authentications.utils.SpringContextUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.provider.authentication.BearerTokenExtractor;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * @ClassName BearerTokenExtractor
 * @Author xiezhuocai
 * @Description TODO
 * @Date 2021/12/18 21:47
 */
public class Oauth2BearerTokenExtractor extends BearerTokenExtractor {

    private JwtAccessTokenConverter jwtAccessTokenConverter;

    public Oauth2BearerTokenExtractor(JwtAccessTokenConverter accessTokenConverter) {
        this.jwtAccessTokenConverter = accessTokenConverter;
    }

    @Override
    public Authentication extract(HttpServletRequest request) {
        String tokenValue = this.extractToken(request);
        if (tokenValue != null) {
            String userStr = parseToken(tokenValue);
            Map<String, InitTokenInfo> tokenInfoMap = SpringContextUtils.getBeansOfType(InitTokenInfo.class);
            if (!tokenInfoMap.isEmpty()){
                for (InitTokenInfo tokenInfo : tokenInfoMap.values()) {
                    tokenInfo.userInfo(userStr);
                }
            }
            PreAuthenticatedAuthenticationToken authentication = new PreAuthenticatedAuthenticationToken(tokenValue, "");
            return authentication;
        } else {
            return null;
        }
    }

    public String parseToken(String token) {
        Map<String, String> key = this.jwtAccessTokenConverter.getKey();
        String jwtKey = key.get("value");
        Claims claims = Jwts.parser().setSigningKey(jwtKey.getBytes(StandardCharsets.UTF_8)).parseClaimsJws(token).getBody();
        String message = (String)claims.get("user_name");
        return message;
    }
}

